%top{
#include<math.h>
#include<string.h>
}
%{
#define ID 0 //identifyer
int IDcount=0;//IDcount
char map[100][100];//符号表
int l_scope=0;//左括号数量
int r_scope=0;//右括号数量
int new_scope=1;//作用域标记符
%}
white [\t\n ]
digit [0-9]
letter [A-Za-z]
id ({letter}|_)({letter}|{digit}|_)*
number [1-9]{digit}*|0
commentbegin "/*"
commentelement .|\n
commentend "*/"
%x COMMENT
%%
{commentbegin} {BEGIN COMMENT; fprintf(yyout,"Begin a comment:\n");}
<COMMENT>{commentelement} {fprintf(yyout,"%s",yytext);}
<COMMENT>{commentend} {BEGIN INITIAL; fprintf(yyout,"\nthis comment End!\n");}
{white}+ ;
{number} {fprintf(yyout,"NUMBER %s %s\n",yytext,yytext);}
"void" {fprintf(yyout,"VOID %s %s\n",yytext," ");}
"char" {fprintf(yyout,"CHAR %s %s\n",yytext," ");}
"int"  {fprintf(yyout,"INT %s %s\n",yytext," ");}
"sizeof" {fprintf(yyout,"SIZEOF %s %s\n",yytext," ");}
"const" {fprintf(yyout,"CONST %s %s\n",yytext," ");}
"return" {fprintf(yyout,"RETURN %s %s\n",yytext," ");}
"continue" {fprintf(yyout,"CONTINUE %s %s\n",yytext," ");}
"break" {fprintf(yyout,"BREAK %s %s\n",yytext," ");}
"if" {fprintf(yyout,"IF %s %s\n",yytext," ");}
"else" {fprintf(yyout,"ELSE %s %s\n",yytext," ");}
"switch" {fprintf(yyout,"SWITCH	%s %s\n",yytext," ");}
"case" {fprintf(yyout,"CASE %s %s\n",yytext," ");}
"default" {fprintf(yyout,"DEFAULT %s %s\n",yytext," ");}
"for" {fprintf(yyout,"FOR %s %s\n",yytext," ");}
"do" {fprintf(yyout,"DO	%s %s\n",yytext," ");}
"while" {fprintf(yyout,"WHILE %s %s\n",yytext," ");}
"scanf" {fprintf(yyout,"SCANF %s %s\n",yytext," ");}
"printf" {fprintf(yyout,"PRINTF %s %s\n",yytext," ");}
{id} {
        int flag = 0;
        int i = 0;
        for(i=IDcount-1;i>0;i--)
        {
           if(strcmp(yytext,map[i])==0)
           {
               flag=1;break;
           }
        }
        if(flag==1&&new_scope!=0)//匹配到已有字符但仍处在旧的作用域
        {
           fprintf(yyout,"ID %s %d\n",yytext,i);
        }
        else//没有匹配到已有字符或者来到了新的作用域
        {
             IDcount++;
             strcpy(map[IDcount-1],yytext);
             new_scope=1;//每次插入一个新字符后需要将作用域标记符重新置1
             fprintf(yyout,"ID %s %d\n",yytext,IDcount-1);
        }
}

"{" {if(l_scope-r_scope==0)
//如果之前左右括号数量一样意味着这个左括号开启了一个新的作用域
                       new_scope=0;
               else
                       new_scope=1;
      l_scope++;
           fprintf(yyout,"LC %s %s\n",yytext," ");}

"}" {r_scope++;
          fprintf(yyout,"RC %s %s\n",yytext," ");}

"[" {fprintf(yyout,"LB %s %s\n",yytext," ");}
"]" {fprintf(yyout,"RB %s %s\n",yytext," ");}
"(" {fprintf(yyout,"LP %s %s\n",yytext," ");}
")" {fprintf(yyout,"RP %s %s\n",yytext," ");}
"~" {fprintf(yyout,"LOGRE %s %s\n",yytext," ");}
"++" {fprintf(yyout,"INPLUS %s %s\n",yytext," ");}
"--" {fprintf(yyout,"INMINUS %s %s\n",yytext," ");}
"!" {fprintf(yyout,"LOCRE %s %s\n",yytext," ");}
"*" {fprintf(yyout,"STAR %s %s\n",yytext," ");}
"/" {fprintf(yyout,"DIVOP %s %s\n",yytext," ");}
"%" {fprintf(yyout,"COMOP %s %s\n",yytext," ");}
"+" {fprintf(yyout,"PLUS %s %s\n",yytext," ");}
"-" {fprintf(yyout,"MINUS %s %s\n",yytext," ");}
">" {fprintf(yyout,"RELG %s %s\n",yytext," ");}
"<" {fprintf(yyout,"RELL %s %s\n",yytext," ");}
">=" {fprintf(yyout,"RELGEQ %s %s\n",yytext," ");}
"<=" {fprintf(yyout,"RELLEQ %s %s\n",yytext," ");}
"==" {fprintf(yyout,"EQUOP %s %s\n",yytext," ");}
"!=" {fprintf(yyout,"UEQUOP %s %s\n",yytext," ");}
"&&" {fprintf(yyout,"ANDAND %s %s\n",yytext," ");}
"||" {fprintf(yyout,"OROR %s %s\n",yytext," ");}
"=" {fprintf(yyout,"EQUAL %s %s\n",yytext," ");}
"/=" {fprintf(yyout,"ASSIGNDIV %s %s\n",yytext," ");}
"*=" {fprintf(yyout,"ASSIGNSTAR %s %s\n",yytext," ");}
"%=" {fprintf(yyout,"ASSIGNCOM %s %s\n",yytext," ");}
"+=" {fprintf(yyout,"ASSIGNPLUS %s %s\n",yytext," ");}
"-=" {fprintf(yyout,"ASSIGNMINUS %s %s\n",yytext," ");}
"," {fprintf(yyout,"COMMA %s %s\n",yytext," ");}
"#" {fprintf(yyout,"SHA %s %s\n",yytext," ");}
";" {fprintf(yyout,"SEMI %s %s\n",yytext," ");}
":" {fprintf(yyout,"COLON %s %s\n",yytext," ");}
%%
int main()
{
  memset(map, 0, sizeof(map));
  yyin=fopen("testin.c","r");
  yyout=fopen("testout.txt","w");
  fprintf(yyout,"token name value\n");
  yylex();
  return 0;
}
int yywrap()
{
return 1;
}

